package com.dog.basics.service.mtkj.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.dog.basics.bean.dto.admin.mtkj.GoodFromDto;
import com.dog.basics.bean.dto.api.mtkj.*;
import com.dog.basics.bean.model.mtkj.*;
import com.dog.basics.bean.model.sys.SysUser;
import com.dog.basics.bean.vo.admin.mtkj.GoodFromVo;
import com.dog.basics.bean.vo.admin.mtkj.GoodSkuFromVo;
import com.dog.basics.bean.vo.admin.mtkj.GoodVo;
import com.dog.basics.bean.vo.api.mtkj.ApiGoodSkuVo;
import com.dog.basics.bean.vo.api.mtkj.ApiGoodsSkuFromVo;
import com.dog.basics.bean.vo.api.mtkj.ApiGoodsVo;
import com.dog.basics.common.util.Json;
import com.dog.basics.common.util.PageParam;
import com.dog.basics.dao.mtkj.*;
import com.dog.basics.security.util.SecurityUtils;
import com.dog.basics.service.mtkj.IMtGoodsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品表 服务实现类
 * </p>
 *
 * @author wph
 * @since 2020-11-09
 */
@Service
@AllArgsConstructor
public class MtGoodsServiceImpl extends ServiceImpl<MtGoodsMapper, MtGoods> implements IMtGoodsService {

    private final MtGoodsMapper goodsMapper;
    private final MtGoodsTypeMapper goodsTypeMapper;
    private final MtShopGoodTypeMapper shopGoodTypeMapper;
    private final MtShoppingMapper shoppingMapper;
    private final MtGoodsSkuMapper goodsSkuMapper;

    /**
     * 根据id查询商品详情
     *
     * @param id
     * @return
     * @author hangdy
     */
    @Override
    public ApiGoodsVo getGoodById(Long id) {
        //根据商品id获取商品详情
        MtGoods goods =this.goodsMapper.selectById(id);
        Validator.validateNotNull(goods,"该商品不存在");
        ApiGoodsVo vo = BeanUtil.toBean(goods, ApiGoodsVo.class);
        MtShopping shopping = shoppingMapper.selectById(goods.getShopId());
        if(shopping !=null ){
            vo.setShopName(ObjectUtil.isNotNull(shopping.getName()) ? shopping.getName() : "");
        }

        MtGoodsType goodsType = goodsTypeMapper.selectById(goods.getTypeId());
        if(goodsType !=null ){
            vo.setShopName(ObjectUtil.isNotNull(goodsType.getName()) ? goodsType.getName() : "");
        }
        MtShopGoodType shopGoodType = shopGoodTypeMapper.selectById(goods.getShopGoodTypeId());
        if(shopGoodType != null){
            vo.setShopName(ObjectUtil.isNotNull(shopGoodType.getName()) ? shopGoodType.getName() : "");
        }
        if(StrUtil.isNotBlank(goods.getImgs())){
            List<String> ts = null;
            try {
                //ts = JSONUtil.toBean(e.getFeedbackImgArray(), ArrayList.class);
                ts= Json.parseArray(goods.getImgs(),String[].class);
            } catch (Exception ex) {
                ts = CollUtil.newArrayList();
            }
            vo.setImgs(ts);
        }
        /**
         * 商品规格信息
         */
        List<MtGoodsSku> goodsSkuList = goodsSkuMapper.selectList(Wrappers.<MtGoodsSku>lambdaQuery().eq(MtGoodsSku::getGoodsId , goods.getId()));
        List<ApiGoodsSkuFromVo> goodSkuFromVos = goodsSkuList.stream().map(e -> BeanUtil.copyProperties(e, ApiGoodsSkuFromVo.class)).collect(Collectors.toList());
        vo.setGoodsSkuList(goodSkuFromVos);
        return vo;
    }

    /**
     * 新增商品
     *
     * @param goodAddDto
     * @return
     * @author hangdy
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveGood(ApiGoodAddDto goodAddDto) {
        MtGoods goods = BeanUtil.copyProperties(goodAddDto, MtGoods.class);

        //查询商铺id检验是否是当前用户
        Validator.validateNotNull(goods.getShopId(),"商铺信息不正确");
        MtShopping shopping = shoppingMapper.selectById(goods.getShopId());
        Validator.validateNotNull(shopping,"商铺不存在");
        Validator.validateEqual(shopping.getUserId(),SecurityUtils.getUser().getUserId(),"商铺信息不正确");

        MtShopGoodType shopGoodType = shopGoodTypeMapper.selectById(goodAddDto.getTypeId());
        Validator.validateNotNull(shopGoodType,"商品类别不存在");
        Validator.validateEqual(shopGoodType.getShopId(),shopping.getId(),"商品类别信息不正确");
        //保存商品总类类别
        goods.setTypeId(shopGoodType.getTypeId());
        //保存店铺商品类别id
        goods.setShopGoodTypeId(goodAddDto.getTypeId());
        if(CollUtil.isNotEmpty(goodAddDto.getImgs())){
            goods.setImgs(JSONUtil.toJsonStr(goodAddDto.getImgs()));
        }

        goods.setCreateTime(DateUtil.currentSeconds());
        goods.setCreateBy(SecurityUtils.getUser().getUserId());
        Validator.validateTrue(this.save(goods), "新增商品失败");

        //保存sku信息List start
        List<ApiGoodsSkuEditDto> skuAddDtos = goodAddDto.getGoodsSkuList();
        List<MtGoodsSku> goodsSkuList = skuAddDtos.stream().map(e -> {
            MtGoodsSku sku = BeanUtil.copyProperties(e,MtGoodsSku.class);
            sku.setGoodsId(goods.getId());
            sku.setSales(0);
            sku.setCreateTime(DateUtil.currentSeconds());
            sku.setCreateBy(SecurityUtils.getUser().getUserId());
            return sku;
        }).collect(Collectors.toList());
        //保存sku信息List end
        for(MtGoodsSku goodsSku : goodsSkuList){
            Validator.validateTrue(retBool(goodsSkuMapper.insert(goodsSku))  ,"商品规格保存失败");
        }

        return Boolean.TRUE;
    }

    /**
     * 修改商品信息
     *
     * @param goodEditDto
     * @return
     * @author hangdy
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean editGood(ApiGoodEditDto goodEditDto) {

        MtGoods goods = this.getById(goodEditDto.getId());
        Validator.validateNotNull(goods, "无此数据");

        //查询商铺id检验是否是当前用户
        Validator.validateNotNull(goods.getShopId(),"商铺信息不正确");
        MtShopping shopping = shoppingMapper.selectById(goods.getShopId());

        Validator.validateEqual(shopping.getUserId(),SecurityUtils.getUser().getUserId(),"商铺信息不正确");
        MtShopGoodType shopGoodType = shopGoodTypeMapper.selectById(goodEditDto.getTypeId());
        Validator.validateNotNull(shopGoodType,"商品类别不存在");
        //判断商品类别信息是否属于该商铺
        Validator.validateEqual(shopGoodType.getShopId(),shopping.getId(),"商品类别信息不正确");
        BeanUtil.copyProperties(goodEditDto, goods);
        if(CollUtil.isNotEmpty(goodEditDto.getImgs())){
            goods.setImgs(JSONUtil.toJsonStr(goodEditDto.getImgs()));
        }

        //保存商品总类类别
        goods.setTypeId(shopGoodType.getTypeId());
        //保存店铺商品类别id
        goods.setShopGoodTypeId(goodEditDto.getTypeId());
        goods.setUpdateTime(DateUtil.currentSeconds());
        goods.setUpdateBy(SecurityUtils.getUser().getUserId());
        Validator.validateTrue(this.updateById(goods), "修改商品失败");

        //保存sku信息List start
        List<ApiGoodsSkuEditDto> skuAddDtos = goodEditDto.getGoodsSkuList();
        List<MtGoodsSku> goodsSkuList = skuAddDtos.stream().map(e -> {
            MtGoodsSku sku = BeanUtil.copyProperties(e,MtGoodsSku.class);
            sku.setGoodsId(goods.getId());
            sku.setUpdateTime(DateUtil.currentSeconds());
            sku.setUpdateBy(SecurityUtils.getUser().getUserId());
            return sku;
        }).collect(Collectors.toList());
        //保存sku信息List end
        for(MtGoodsSku goodsSku : goodsSkuList){
            if(ObjectUtil.isNull(goodsSku.getId())){
                Validator.validateTrue(retBool(goodsSkuMapper.insert(goodsSku))  ,"商品规格保存失败");
            }else {
                Validator.validateTrue(retBool(goodsSkuMapper.updateById(goodsSku))  ,"商品规格保存失败");
            }

        }
        return Boolean.TRUE;
    }

    /**
     * 删除商品信息
     *
     * @param id
     * @return
     * @author hangdy
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteGood(Long id) {
        MtGoods goods = this.getById(id);
        Validator.validateNotNull(goods, "无此数据");

        //查询商铺id检验是否是当前用户
        Validator.validateNotNull(goods.getShopId(),"商铺信息不正确");
        MtShopping shopping = shoppingMapper.selectById(goods.getShopId());
        Validator.validateNotNull(shopping,"商铺信息不正确");
        Validator.validateEqual(shopping.getUserId(),SecurityUtils.getUser().getUserId(),"商铺信息不正确");

        /**
         * 查询是否有绑定sku（商品规格）
         */
        List<MtGoodsSku> goodsSkuList = goodsSkuMapper.selectList(Wrappers.<MtGoodsSku>lambdaQuery().eq(MtGoodsSku::getGoodsId, id));
        Validator.validateNotNull(goodsSkuList, "已绑定商品规格不能删除该商品");

        Validator.validateTrue(this.removeById(id), "删除商品失败");

        return Boolean.TRUE;
    }

    /**
     * 对商品进行上架下架
     * （0下架 1上架）
     * 根据商品当前的status进行判断，如果是0修改为1如果是1修改为0
     * 如果status不是 0 和 1 抛 RuntimeException 当前商品不能执行该操作
     *
     * @param: id
     * @return: java.lang.Boolean
     * @author hangdy
     * @date: 2020/11/12 9:59
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean goodUpOrDown(Long id) {
        MtGoods goods = this.getById(id);

        Validator.validateNotNull(goods, "未找到该商品");

        //查询商铺id检验是否是当前用户
        Validator.validateNotNull(goods.getShopId(),"商铺信息不正确");
        MtShopping shopping = shoppingMapper.selectById(goods.getShopId());
        Validator.validateNotNull(shopping,"商铺不存在");
        Validator.validateEqual(shopping.getUserId(),SecurityUtils.getUser().getUserId(),"商铺信息不正确");

        if (goods.getStatus() != 0 && goods.getStatus() != 1) {
            throw new RuntimeException("当前商品不能执行该操作");
        }
        switch (goods.getStatus()) {
            case 0:
                goods.setStatus(1);
                break;
            case 1:
                goods.setStatus(0);
                break;
        }
        Validator.validateTrue(this.updateById(goods), "操作商品失败");
        return Boolean.TRUE;
    }





    /**
     * 分页获取商铺商品列表
     * 1.搜索商品 根据商品名称搜索所有商品
     * 2.获取店铺商品
     * 3.获取类别商品
     * 4.获取商铺类别商品
     * 5.根据商品上下架状态查询
     *
     * @param page
     * @param goodFromDto
     * @return
     * @author hangdy
     */
    @Override
    public IPage<ApiGoodsVo> getPageList(PageParam page, ApiGoodFromDto goodFromDto) {
        String limit = " order By create_time desc";
        if (ObjectUtil.isNotNull(goodFromDto.getSales())) {
            if (goodFromDto.getSales() == 0) {
                limit = " order By sales desc";
            } else {
                limit = " order By sales asc";
            }
        }
        if (ObjectUtil.isNotNull(goodFromDto.getPrice())) {
            if (goodFromDto.getPrice() == 0) {
                limit = " order By price desc";
            } else {
                limit = " order By price asc";
            }
        }
        //LambdaQueryWrapper
        /* 如果只有商品名称 根据商品名称搜索所有商品
         * 如果只有商铺id 查询该商铺商品信息
         * 如果只有类别id 查询该类商品信息
         * 如果既有商铺id又有类别id 查询该商铺该类别商品信息
         *
         *
         */
        Long typeId = null;
        if(ObjectUtil.isNull(goodFromDto.getShopId()) && ObjectUtil.isNotNull(goodFromDto.getGoodTypeId())){
            typeId = goodFromDto.getGoodTypeId();
            goodFromDto.setGoodTypeId(null);
        }
        IPage iPage = this.page(page, Wrappers.<MtGoods>lambdaQuery()
                        .like(ObjectUtil.isNotNull(goodFromDto.getGoodName()), MtGoods::getName, goodFromDto.getGoodName())
                        .eq(ObjectUtil.isNotNull(goodFromDto.getShopId()), MtGoods::getShopId, goodFromDto.getShopId())
                        .eq(ObjectUtil.isNotNull(goodFromDto.getGoodTypeId()), MtGoods::getShopGoodTypeId, goodFromDto.getGoodTypeId())
                        .eq(ObjectUtil.isNotNull(goodFromDto.getStatus()), MtGoods::getStatus, goodFromDto.getStatus())
                        .eq(ObjectUtil.isNotNull(typeId), MtGoods::getTypeId, typeId)
                .last(limit)
                //排序使用
        );

        //将MtGoods类型数据转变成GoodsVo类型
        List<MtGoods> records = iPage.getRecords();
        iPage.setRecords(records.stream().map(e -> {
            ApiGoodsVo apiGoodsVo = BeanUtil.toBean(e, ApiGoodsVo.class);
            //查询商品所属类别 start
            MtGoodsType goodsType = goodsTypeMapper.selectById(e.getTypeId());
            apiGoodsVo.setTypeName(ObjectUtil.isNull(goodsType) ? "" : goodsType.getName());
            //查询商品所属类别 end


            MtShopGoodType shopGoodType = shopGoodTypeMapper.selectById(e.getShopGoodTypeId());
            apiGoodsVo.setShopGoodTypeName(ObjectUtil.isNotNull(shopGoodType) ? shopGoodType.getName() : "");

            //查询所属商铺信息 start
            MtShopping shopping = shoppingMapper.selectById(e.getTypeId());
            apiGoodsVo.setShopName(ObjectUtil.isNull(shopping) ? "" : shopping.getName());
            //查询所属商铺信息 end
            if(StrUtil.isNotBlank(e.getImgs())){
                List<String> ts = null;
                try {
                    //ts = JSONUtil.toBean(e.getFeedbackImgArray(), ArrayList.class);
                    ts= Json.parseArray(e.getImgs(),String[].class);
                } catch (Exception ex) {
                    ts = CollUtil.newArrayList();
                }
                apiGoodsVo.setImgs(ts);
            }
            return apiGoodsVo;
        }).collect(Collectors.toList()));

        return iPage;
    }

    /**
     * 根据商品id获取商品规格信息
     * 如果商品没有sku信息则返回空list
     *                                          目前没有被使用
     *                                          目前没有被使用
     *                                          目前没有被使用
     * @param goodId
     * @return
     */
    public List<ApiGoodSkuVo> findGoodsSku(Long goodId) {
        List<MtGoodsSku> mtGoodsSkuList = goodsSkuMapper.selectList(new LambdaQueryWrapper<MtGoodsSku>()
                .eq(MtGoodsSku::getGoodsId, goodId));
        List<ApiGoodSkuVo> apiGoodSkuVoList = new ArrayList<>();
        for (MtGoodsSku goodsSku : mtGoodsSkuList) {
            apiGoodSkuVoList.add(BeanUtil.copyProperties(goodsSku, ApiGoodSkuVo.class));
        }
        return apiGoodSkuVoList;
    }

    /**
     * Admin服务
     *  删除商品
     * @param: id
     * @returns
     * @author hangdy
     * @date: 2020/11/14 16:34
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean adminDeleteGood(Long id) {
        //2.查看商品是否存在
        MtGoods goods = this.getById(id);
        Validator.validateNotNull(goods,"商品不存在");

        /**
         * 查询是否有绑定sku（商品规格）
         */
        List<MtGoodsSku> goodsSkuList = goodsSkuMapper.selectList(Wrappers.<MtGoodsSku>lambdaQuery().eq(MtGoodsSku::getGoodsId, id));
        Validator.validateNotNull(goodsSkuList, "已绑定商品规格不能删除该商品");

        Validator.validateTrue(this.removeById(id),"删除商品失败");
        return Boolean.TRUE;
    }

    /**
     * Admin服务
     *  获取商品详情
     * @param id
     * @return
     */
    @Override
    public GoodVo adminfindGood(Long id) {
        MtGoods goods = this.getById(id);
        Validator.validateNotNull(goods,"商品不存在");
        GoodVo goodVo = BeanUtil.copyProperties(goods,GoodVo.class);

        MtGoodsType goodsType = goodsTypeMapper.selectById(goods.getTypeId());
        if(goodsType != null){
            goodVo.setTypeName(ObjectUtil.isNotNull(goodsType)? goodsType.getName() : "");

        }
        MtShopping shopping = shoppingMapper.selectById(goods.getShopId());
        if(shopping != null){
            goodVo.setTypeName(ObjectUtil.isNotNull(shopping)? shopping.getName() : "");

        }
        MtShopGoodType shopGoodType = shopGoodTypeMapper.selectById(goods.getShopGoodTypeId());
        if(shopGoodType != null){
            goodVo.setTypeName(ObjectUtil.isNotNull(shopGoodType)? shopGoodType.getName() : "");

        }

        /**
         * 商品规格信息
         */
        List<MtGoodsSku> goodsSkuList = goodsSkuMapper.selectList(Wrappers.<MtGoodsSku>lambdaQuery().eq(MtGoodsSku::getGoodsId , goods.getId()));
        List<ApiGoodsSkuFromVo> goodSkuFromVos = goodsSkuList.stream().map(e -> BeanUtil.copyProperties(e, ApiGoodsSkuFromVo.class)).collect(Collectors.toList());
        goodVo.setGoodsSkuList(goodSkuFromVos);
        return goodVo;
    }


    /**
     * Admin服务
     *  查询商品
     * @param: page
     * @param: fromDto
     * @returns
     * @author hangdy
     * @date: 2020/11/14 16:53
     */
    @Override
    public IPage<GoodFromVo> adminFindGoodList(PageParam page, GoodFromDto fromDto) {
        IPage iPage = this.page(page, Wrappers.<MtGoods>lambdaQuery()
                .like(ObjectUtil.isNotNull(fromDto.getName()), MtGoods::getName, fromDto.getName())
                .eq(ObjectUtil.isNotNull(fromDto.getTypeId()), MtGoods::getShopGoodTypeId, fromDto.getTypeId())
                .eq(ObjectUtil.isNotNull(fromDto.getShopId()), MtGoods::getShopId, fromDto.getShopId())
                .eq(ObjectUtil.isNotNull(fromDto.getStatus()), MtGoods::getStatus, fromDto.getStatus())
                .eq(ObjectUtil.isNotNull(fromDto.getIsHot()), MtGoods::getIsHot, fromDto.getIsHot())
                .eq(ObjectUtil.isNotNull(fromDto.getIsRecommend()), MtGoods::getIsRecommend, fromDto.getIsRecommend())
                .eq(ObjectUtil.isNotNull(fromDto.getIsNew()), MtGoods::getIsNew, fromDto.getIsNew())
                .eq(ObjectUtil.isNotNull(fromDto.getShopGoodTypeId()), MtGoods::getShopGoodTypeId, fromDto.getShopGoodTypeId())

        );

        //将MtGoods类型数据转变成GoodsVo类型
        List<MtGoods> records = iPage.getRecords();
        List<GoodFromVo> goodFromVoList = records.stream().map(e -> {
            GoodFromVo vo = BeanUtil.copyProperties(e,GoodFromVo.class);

            MtShopping shopping = shoppingMapper.selectById(e.getShopId());
            if(shopping != null){
                vo.setShopName(ObjectUtil.isNotNull(shopping.getName()) ? shopping.getName() : "");
            }
            MtGoodsType goodsType = goodsTypeMapper.selectById(e.getTypeId());
            if(goodsType != null){
                vo.setTypeName(ObjectUtil.isNotNull(goodsType.getName()) ? goodsType.getName() : "");
            }
            MtShopGoodType shopGoodType = shopGoodTypeMapper.selectById(e.getShopGoodTypeId());
            if(shopGoodType != null){
                vo.setShopGoodTypeName(ObjectUtil.isNotNull(shopGoodType.getName()) ? shopGoodType.getName() : "");
            }
            return vo;
        }).collect(Collectors.toList());

        iPage.setRecords(goodFromVoList);
        return iPage;
    }
}
